package com.sptus.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sptus.aop.AppIntercept;
import com.sptus.config.DataLoaderConfig;
import com.sptus.entity.*;
import com.sptus.service.*;
import com.sptus.system.domain.Equipment;
import com.sptus.system.domain.vo.AppInfo;
import com.sptus.system.service.ISptDevLogService;
import com.sptus.util.SHA256Util;
import com.sptus.vo.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.concurrent.Semaphore;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@Api(tags = "app端设备接口")
@RequestMapping("/sys/app")
public class AppEquipmentController {
    @Autowired
    private IAppEquipmentService equipmentService;
    @Autowired
    ISptUserService sptUserService;

    @Autowired
    ISptUserEquipmentService sptUserEquipmentService;

    @Autowired
    ISptUserParentService sptUserParentService;
    @Autowired
    IUsCitiesService iUsCitiesService;
    @Autowired
    IUsStatesService iUsStatesService;




    @GetMapping("deviceStateAddress")
    @ApiOperation(value="获取州地址", notes="获取州地址")
    @AppIntercept
    public Result<Object> deviceStateAddress(){
        List<UsStates> usStates = iUsStatesService.getBaseMapper().selectList(null);
        Result<Object> result = new Result<>();
        result.setResult(usStates);
        result.setCode(200);
        return result;
    };
    @GetMapping("deviceCitiesAddress")
    @ApiOperation(value="获取城市地址", notes="获取城市地址")
    @AppIntercept
    public Result<Object> deviceCitiesAddress(String citiesName,String stateId){
        Result<Object> result = new Result<>();
        if(StringUtils.isEmpty(stateId)){
            return  result.error500("Please enter state id");
        }
        LambdaQueryWrapper<UsCities> iUsCitiesServiceLambdaQueryWrapper = new LambdaQueryWrapper<>();
        iUsCitiesServiceLambdaQueryWrapper.like(!StringUtils.isEmpty(citiesName),UsCities::getCity,citiesName);
        iUsCitiesServiceLambdaQueryWrapper.eq(UsCities::getIdState,stateId);
        List<UsCities> usCities = iUsCitiesService.getBaseMapper().selectList(iUsCitiesServiceLambdaQueryWrapper);
        result.setResult(usCities);
        result.setCode(200);
        return result;
    };


    @AppIntercept
    @ApiOperation(value="getVersion-版本", notes="equipment-添加")
    @GetMapping(value = "/getVersion")
    public Result<String> getVersion(String type) {
        type=StringUtils.isEmpty(type)?"apple":type;
        Result<String> ok = Result.ok();
        String s="";
        if(type.equals("android")){
             s = DataLoaderConfig.getGlobalData().get("spt.android.version");
        }else {
          s=  DataLoaderConfig.getGlobalData().get("spt.apple.version") ;
        }
        ok.setResult(s);
        return ok;
    }

    @AppIntercept
    @ApiOperation(value="得到设备城市", notes="得到设备城市")
    @GetMapping(value = "/getEquipmentCity")
    public Result<Object> getEquipmentCity(String  sn) {
        Result<Object> ok = Result.ok();
        HashMap<String,String>  usCities= equipmentService.getEquipmentCity(sn);
        ok.setResult(usCities);
        return ok;
    }


//    @AutoLog(value = "设备添加")
    @AppIntercept
    @ApiOperation(value="equipment-添加", notes="equipment-添加")
    @PostMapping(value = "/add")
    public Result<String> add(@RequestBody Equipment equipment, SptUser sptUser) {
        Integer id = sptUser.getId();
        equipment.setSignBy(id+"");
        equipment.setStatus("2");
        if (StringUtils.isEmpty(equipment)){
            equipment.setName(equipment.getSn());
        }
        LambdaQueryWrapper<Equipment> objectLambdaQueryWrapper = new LambdaQueryWrapper<>();
        objectLambdaQueryWrapper.eq(Equipment::getSn,equipment.getSn());
        List<Equipment> equipment1 = equipmentService.getBaseMapper().selectList(objectLambdaQueryWrapper);
        if (equipment1.size()>0){
            LambdaQueryWrapper<SptUserEquipment> sptUserEquipmentLambdaQueryWrapper = new LambdaQueryWrapper<>();
            sptUserEquipmentLambdaQueryWrapper.eq(SptUserEquipment::getEquipmentId,equipment1.get(0).getSn());
            sptUserEquipmentLambdaQueryWrapper.eq(SptUserEquipment::getUserId,sptUser.getId());
            SptUserEquipment sptUserEquipmentObj = sptUserEquipmentService.getBaseMapper().selectOne(sptUserEquipmentLambdaQueryWrapper);
            if(!ObjectUtils.isEmpty(sptUserEquipmentObj)){
                return Result.OK("successfully added！");
            }
        }else {
            equipmentService.save(equipment);
        }
        SptUserEquipment sptUserEquipment = new SptUserEquipment();
        sptUserEquipment.setEquipmentId(equipment.getSn());
        sptUserEquipment.setUserId(sptUser.getId()+"");
        sptUserEquipment.setDevName(equipment.getName());
        sptUserEquipmentService.save(sptUserEquipment);

        return Result.OK("successfully added！");
    }
//    @AutoLog(value = "设备编辑")
    @AppIntercept
    @ApiOperation(value="设备编辑", notes="设备编辑")
    @PostMapping(value = "/update")
    public Result<String> update(@RequestBody Equipment equipment,SptUser sptUser) {
        Integer id = sptUser.getId();
        equipment.setSignBy(id+"");
        equipment.setStatus(equipment.getStatus());
        LambdaQueryWrapper<SptUserParent> sptUserParentLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sptUserParentLambdaQueryWrapper.eq(SptUserParent::getUserId,sptUser.getId());
        sptUserParentLambdaQueryWrapper.eq(SptUserParent::getState,"1");
        List<HashMap<String,String>> sptUserParents = sptUserParentService.selectListInfo(sptUserParentLambdaQueryWrapper);
        ArrayList<String> ids = new ArrayList<>();
        if(sptUserParents.size()>0){
            ids.add(sptUserParents.get(0).get("parent_id"));
        }
        ids.add(id+"");
        LambdaQueryWrapper<SptUserEquipment> sptUserEquipmentLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sptUserEquipmentLambdaQueryWrapper.eq(SptUserEquipment::getEquipmentId,equipment.getSn());
        sptUserEquipmentLambdaQueryWrapper.in(SptUserEquipment::getUserId,ids);
        SptUserEquipment sptUserEquipment = sptUserEquipmentService.getBaseMapper().selectOne(sptUserEquipmentLambdaQueryWrapper);
        LambdaQueryWrapper<Equipment> objectLambdaQueryWrapper = new LambdaQueryWrapper<>();
        objectLambdaQueryWrapper.eq(Equipment::getSn,equipment.getSn());
//        objectLambdaQueryWrapper.eq(Equipment::getSignBy,sptUser.getId());
//        Equipment equipmentInfo = equipmentService.getBaseMapper().selectOne(objectLambdaQueryWrapper);
        if (sptUserEquipment!=null){
            equipmentService.update(equipment,objectLambdaQueryWrapper);
            sptUserEquipment.setDevName(equipment.getName());
            sptUserEquipmentService.update(sptUserEquipment,sptUserEquipmentLambdaQueryWrapper);
            return  Result.OK("modify successfully");
        }

        return Result.OK("Device does not exist！");
    }

//    @AutoLog(value = "设备-通过id删除")
    @ApiOperation(value="设备-通过id删除", notes="设备-通过id删除")
    @DeleteMapping(value = "/delete")
    @AppIntercept
    public Result<String> delete(@RequestParam(name="id",required=true) String id,SptUser sptUser) {

        LambdaQueryWrapper<Equipment> lambdaQueryWrapper = new LambdaQueryWrapper<Equipment>();
        lambdaQueryWrapper.eq(Equipment::getId,id);
        Equipment equipment = equipmentService.getBaseMapper().selectOne(lambdaQueryWrapper);
        LambdaQueryWrapper<SptUserEquipment> sptUserEquipmentLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sptUserEquipmentLambdaQueryWrapper.eq(SptUserEquipment::getEquipmentId,equipment.getSn());
        sptUserEquipmentLambdaQueryWrapper.eq(SptUserEquipment::getUserId,sptUser.getId());
        sptUserEquipmentService.getBaseMapper().delete(sptUserEquipmentLambdaQueryWrapper);
        if (equipment.getStatus().equals("2")){
            equipmentService.getBaseMapper().delete(lambdaQueryWrapper);
        }
        return Result.OK("successfully delete!");
    }
    static  Semaphore  semaphore=new Semaphore(1);
//    @AutoLog(value = "设备查询")
    @ApiOperation(value="设备查询", notes="设备查询")
    @AppIntercept
    @PostMapping(value = "/selectEquipment")
    public Result<Object> selectEquipment(@RequestBody Equipment equipment,SptUser sptUser) {

        LambdaQueryWrapper<SptUserEquipment> sptUserEquipmentLambdaQueryWrapper = new LambdaQueryWrapper<>();
//        sptUserEquipmentLambdaQueryWrapper.eq(SptUserEquipment::getEquipmentId,equipment.getSn());
        sptUserEquipmentLambdaQueryWrapper.eq(SptUserEquipment::getUserId,sptUser.getId());
        List<SptUserEquipment> sptUserEquipments = sptUserEquipmentService.getBaseMapper().selectList(sptUserEquipmentLambdaQueryWrapper);
        ArrayList<Equipment> equipments = new ArrayList<>();
        List<String> collect = sptUserEquipments.stream().map(e -> e.getEquipmentId()).collect(Collectors.toList());

        QueryWrapper<Equipment> equipmentLambdaQueryWrapper = new QueryWrapper<>();
        equipmentLambdaQueryWrapper.in("equipment.sn",collect);

        Map<String, Equipment> collectMap = equipmentService.selectListInfo(equipmentLambdaQueryWrapper).stream().collect(Collectors.toMap(Equipment::getSn, Function.identity(), (value1, value2) -> value1));
        for (SptUserEquipment sptUserEquipment : sptUserEquipments) {
            Equipment equipmentObj = new Equipment();
            equipmentObj.setSn(sptUserEquipment.getEquipmentId());
            equipmentObj.setName(sptUserEquipment.getDevName());
            Equipment equipment1 = collectMap.get(sptUserEquipment.getEquipmentId());
            equipmentObj.setStatus(equipment1.getStatus());
            equipments.add(equipmentObj);
        }

//        LambdaQueryWrapper<Equipment> equipmentLambdaQueryWrapper = new LambdaQueryWrapper<>();
//        equipmentLambdaQueryWrapper.eq(Equipment::getSn,equipment.getSn());
//        equipmentLambdaQueryWrapper.eq(!StringUtils.isEmpty(equipment.getStatus()),Equipment::getStatus,equipment.getStatus());
//        equipmentLambdaQueryWrapper.in(Equipment::getSn, collect);
//        List<Equipment> equipmentlist = equipmentService.getBaseMapper().selectList(equipmentLambdaQueryWrapper);
        Result<Object> result = Result.OK("Query success");
        result.setResult(equipments);
        return result;
    }

//    @AutoLog(value = "设备查询")
    @ApiOperation(value="通过模型查询设备", notes="通过磨板查询设备")
    @AppIntercept
    @GetMapping(value = "/selectModelEquipment")
    public Result<Object> selectModelEquipment(AppInfo appInfo, SptUser sptUser) {
        return selectModelEquipmentRealize(appInfo,sptUser);
    }
//    @AutoLog(value = "设备查询")
    @ApiOperation(value="查询设备列表（带温度等详细信息）", notes="通过磨板查询设备")
    @AppIntercept
    @GetMapping(value = "/selectEquipmentInfo")
    public Result<Object> selectEquipmentInfo( AppInfo appInfo, SptUser sptUser) {
        return selectModelEquipmentRealize(appInfo,sptUser);
    }
//    @AutoLog(value = "设备升级")
    @ApiOperation(value="设备升级", notes="通过磨板查询设备")
    @AppIntercept
    @GetMapping(value = "/equipmentUpgrade")
    public Result<Object> equipmentUpgrade( AppInfo appInfo, SptUser sptUser) {
        String password = SHA256Util.getSHA256("Voltronic" + appInfo.getSn() + "Power");
        password = SHA256Util.getSHA256(password);
        password = password.substring(password.length() - 6);
        String url ="https://www.tumcapp.com/app/api/mobile/device/updateDeviceOTA";
        return selectModelEquipmentRealize(appInfo,sptUser);
    }

    public Result<Object> selectModelEquipmentRealize( AppInfo appInfo, SptUser sptUser) {

        ArrayList<String> ids = new ArrayList<>();
        LambdaQueryWrapper<SptUserParent> sptUserParentLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sptUserParentLambdaQueryWrapper.eq(SptUserParent::getUserId,sptUser.getId());
        sptUserParentLambdaQueryWrapper.eq(SptUserParent::getState,"1");
        List<HashMap<String,String>> sptUserParents = sptUserParentService.selectListInfo(sptUserParentLambdaQueryWrapper);
        if(sptUserParents.size()>0){
            ids.add(sptUserParents.get(0).get("parent_id"));
        }
        ids.add(sptUser.getId()+"");

        LambdaQueryWrapper<SptUserEquipment> sptUserEquipmentLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sptUserEquipmentLambdaQueryWrapper.in(SptUserEquipment::getUserId,ids);

        List<SptUserEquipment> sptUserEquipments = sptUserEquipmentService.getBaseMapper().selectList(sptUserEquipmentLambdaQueryWrapper);
        ArrayList<Equipment> equipmentlist = new ArrayList<>();
//        List<String> collect = sptUserEquipments.stream().map(e -> e.getEquipmentId()).collect(Collectors.toList());
        List<String> collect = sptUserEquipments.stream().map(e -> e.getEquipmentId()).collect(Collectors.toList());
                if(  collect.size()==0){
                    Result<Object> result = Result.OK("Query success");
                    result.setResult(equipmentlist);
                    return    result;
                }
        QueryWrapper<Equipment> equipmentLambdaQueryWrapper = new QueryWrapper<>();
        equipmentLambdaQueryWrapper.in("equipment.sn",collect);

        Map<String, Equipment> collectMap = equipmentService.selectListInfo(equipmentLambdaQueryWrapper).stream().collect(Collectors.toMap(Equipment::getSn, Function.identity(), (value1, value2) -> value1));
        for (SptUserEquipment sptUserEquipment : sptUserEquipments) {
            Equipment equipmentObj  = collectMap.get(sptUserEquipment.getEquipmentId());

            if(!StringUtils.isEmpty(equipmentObj)){
                equipmentObj.setName(sptUserEquipment.getDevName());
                equipmentlist.add(equipmentObj);
            }

        }

        Result<Object> result = Result.OK("Query success");
        result.setResult(equipmentlist);
        return result;
    }





}
